<script setup lang="ts">
import {ref, computed, onBeforeMount} from 'vue'
import type {FormInst} from 'naive-ui'
import {useMessage} from 'naive-ui';
import {config} from '@/config';
import CustomIcon from '@/components/CustomIcon'
import {UseAppStore} from "@/stores/app.ts";
import {userStore} from '@/stores/user.ts';

import {getRequest} from "@/api";
import {getLocalStorage, removeLocalStorage, setLocalStorage} from "@/utils/storage.ts";
import {Base64} from 'js-base64';
import {useRoute, useRouter} from "vue-router";
import {Moon, Sun} from "@vicons/tabler";

const LoginLeftImg = new URL('@/assets/img/login_left/pana.svg', import.meta.url).href;

const appStore = UseAppStore();
const userStores = userStore()
const message = useMessage();
const route = useRoute();
const router = useRouter();

interface CaptchaData {
  captcha: string
  captcha_key: string
}

interface Login {
  username: null | string,
  password: null | string,
  verification_code: string,
  captcha: string,
  captcha_key: null | string | unknown | never,
  remember: boolean,
}

const loginFormRef = ref<FormInst | null | never>(null);
const LoadingLoginBtn = ref<boolean>(false);
//登录表单
const loginForm = ref<Login>({
  username: null,
  password: null,
  verification_code: '',
  captcha: '',
  captcha_key: null,
  remember: false,
})

//登录表单验证
const loginFormRules = computed(() => {
  return {
    username: {
      required: true,
      trigger: ["blur", "input"],
      message: "请输入登录账号",
    },
    password: {
      required: true,
      trigger: ["blur", "input"],
      validator: (_rule: never, value: string | never[]) => {
        return new Promise<void>((resolve, reject) => {
          if (!value || value === " ") {
            reject(Error("请输入登录密码"));
          } else if (value && value.length < 6) {
            reject(Error("请输入6位或6位以上的登录密码"));
          } else {
            resolve();
          }
        });
      },
    },
    verification_code: {
      required: true,
      trigger: ["blur", "input"],
      message: "请输入验证码",
    },
  }
})

//执行登录
const handelLogin = (e: MouseEvent) => {
  e.preventDefault();
  loginFormRef.value?.validate(async (errors) => {
    if (!errors) {
      LoadingLoginBtn.value = true;
      const loginData = {
        username: loginForm.value.username,
        password: loginForm.value.password,
        captcha: loginForm.value.verification_code,
        captcha_key: loginForm.value.captcha_key
      };
      try {
        await userStores.login(loginData);
        remPws();
        const toPath = decodeURIComponent((route.query?.redirect || '/') as string);
        message.success('登录成功，即将进入系统', {
          duration: 1500,
          onLeave() {
            if (route.name === "login") {
              router.replace({name: 'home'});
            } else {
              router.replace(toPath)
            }
          }
        });
      } catch (error: unknown) {
        const err = error as ResponseResult;
        message.error(err.message || '登录失败');
      } finally {
        LoadingLoginBtn.value = false;
      }
    }
  })
}


//获取验证码
const getCaptcha = async () => {
  const response = await getRequest<ResponseResult<CaptchaData>>('/captcha');
  const captchaData = response.data as unknown as CaptchaData;
  // 使用可选链操作符安全访问
  loginForm.value.captcha = captchaData.captcha;
  loginForm.value.captcha_key = captchaData.captcha_key;

}
// 记住密码
const remPws = () => {
  if (loginForm.value.remember) {
    const password = loginForm.value.password && Base64.encode(loginForm.value.password) as string; // base64加密
    setLocalStorage("userName", loginForm.value.username);
    setLocalStorage("password", password);
  } else {
    removeLocalStorage("userName");
    removeLocalStorage("password");
  }
};
// 获取本地储存的密码
const getPwd = () => {
  const username = getLocalStorage("userName") as string;
  if (username) {
    const pass = getLocalStorage("password") as string;
    loginForm.value.username = username;
    if (pass != null) {
      loginForm.value.password = Base64.decode(pass);
    } // base64解密
    loginForm.value.remember = true;
  }
};
onBeforeMount(() => {
  getPwd();
  getCaptcha();
})
</script>

<template>
  <div class="login-container">
    <div class="login-container-box">
      <div class="login-container-box-left">
        <img :src="LoginLeftImg" alt=""
             style="width: 100%;height: 400px; user-select: none;  pointer-events: none;"
             draggable="false">
      </div>
      <div class="login-container-box-right">
        <div style="position: relative">
          <header>
            <h1 style="margin-block-start: 0;font-size: 34px;line-height: 34px;margin-block-end: 0;font-family: serif;">
              欢迎使用
            </h1>
            <h3 style="color: rgb(75 85 99);margin-block-start: 0.4em">{{ config.Title }}</h3>
          </header>
          <div class="change-theme" @click="appStore.changeTheme">
<!--            {{appStore.appTheme=='dark'?'浅色':'深色'}}-->
            <n-icon :size="18">
              <Sun v-if="appStore.appTheme=='dark'"/>
              <Moon v-if="appStore.appTheme=='light'"/>
            </n-icon>
          </div>
        </div>

        <n-form ref="loginFormRef"
                style="padding-top: 20px"
                :model="loginForm"
                :rules="loginFormRules"
                size="large"
                :show-label="false"
                :show-require-mark="false"
                @keydown.enter.prevent="handelLogin">
          <n-form-item path="username">
            <n-input
                v-model:value="loginForm.username"
                placeholder="请输入登录账号" clearable>
              <template #prefix>
                <custom-icon component="tabler-User" :size="22"/>
              </template>
            </n-input>
          </n-form-item>
          <n-form-item path="password">
            <n-input v-model:value="loginForm.password"
                     type="password"
                     placeholder="请输入登录密码"
                     show-password-on="click" clearable>
              <template #prefix>
                <custom-icon component="material-LockFilled" :size="20"/>
              </template>
            </n-input>
          </n-form-item>
          <n-form-item path="verification_code">
            <n-flex style="gap: 6px 6px;">
              <div style="width: 190px;">
                <n-input v-model:value="loginForm.verification_code"
                         type="text"
                         placeholder="请输入验证码"
                         maxlength="4"
                         clearable>
                  <template #prefix>
                    <custom-icon component="material-PhotoOutlined" :size="20"/>
                  </template>
                </n-input>
              </div>
              <div style="height: 38px; width: 100px;background-color: #DCDFE6;cursor: pointer;border-radius: 4px;">
                <img v-if="loginForm.captcha" :src="loginForm.captcha" alt="验证码"
                     style="width: 100%; height: 100%;border-radius: 4px;" @click="getCaptcha"/>
              </div>
            </n-flex>
          </n-form-item>
          <n-form-item>
            <div style="display: flex;justify-content: space-between;width: 100%;margin-top: 15px">
              <n-checkbox v-model:checked="loginForm.remember">
                记住我
              </n-checkbox>
            </div>
          </n-form-item>
          <n-form-item :show-feedback="false">
            <n-button type="primary" size="large" block :loading="LoadingLoginBtn" style="font-weight: 600"
                      @click="handelLogin">
              登录
            </n-button>
          </n-form-item>
        </n-form>
      </div>
    </div>
    <div class="login-container-footer">
      <p style="bottom: 0 !important;">
        {{ appStore.copyright }} <span style="padding-left: 20px;">{{
          appStore.tel_email_qq
        }}</span>
        <br/>
        本系统支持Edge、Firefox、Chrome、Safari、360极速(极速模式)等现代浏览器，不支持IE浏览器
      </p>
    </div>
  </div>

</template>

<style lang="scss">

.login-container {
  width: 100%;
  height: 100vh;
  transition: all 0.3s;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  -o-transition: all 0.3s;
  display: grid;
  justify-content: center;
  align-items: end;

  background-image: var(--login-bg-color);

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    //background-image: url("@/assets/img/login_bg.svg");

  }

  &-box {
    width: 780px;
    height: 480px;
    position: relative;
    display: flex;
    background-color: var(--login-box-bg-color) !important;
    border-radius: .375rem;
    transition: all 0.3s;
    -webkit-transition: all 0.3s;
    -moz-transition: all 0.3s;
    -o-transition: all 0.3s;
    z-index: 1; /* 确保子元素在伪元素上面 */
    box-shadow: rgba(0, 0, 0, 0.05) 0 4px 10px 3px, rgba(0, 0, 0, 0.04) 0 4px 6px 2px, rgba(0, 0, 0, 0.08) 0 2px 3px -3px;

    &-left {
      width: 480px;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: var(--login-box-left-bg-color);
      border-radius: .375rem 0 0 .375rem;
      transition: all 0.3s;
      -webkit-transition: all 0.3s;
      -moz-transition: all 0.3s;
      -o-transition: all 0.3s;
    }

    &-right {
      width: 352px;
      border-radius: 0 .375rem .375rem 0;
      padding: 1.5rem;
      transition: all 0.3s;
      -webkit-transition: all 0.3s;
      -moz-transition: all 0.3s;
      -o-transition: all 0.3s;
    }
  }

}

.login-container-footer {
  z-index: 2;
  transition: all 0.3s;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  -o-transition: all 0.3s;
  text-align: center;

}
.change-theme{
  position: absolute;
  top: 0;
  right: 0;
  cursor: pointer;
}
</style>
